<!-- 关联表单 -->
<template>
  <view>
    <van-field
      v-show="!props.hidden"
      v-model="selectedLabel"
      is-link
      :readonly="true"
      :label="props.formItem?.title"
      :placeholder="props.placeholder"
      :required="required"
      :rules="formRules"
      :input-align="FieldInputAlign.DEFAULT"
      @click="!props.readonly && (showPicker = true)"
    />
    <van-popup v-model:show="showPicker" round position="bottom">
      <van-picker
        title="请选择"
        :columns="options"
        :columns-field-names="customFieldName"
        @confirm="onConfirm"
        @cancel="onCancel"
      />
    </van-popup>
  </view>
</template>
<script setup lang="ts">
  import { isEmpty, isNotEmpty } from '@/utils/is';
  import { computed, ref, watch } from 'vue';
  import { evalFormual } from '@/utils/evalFormual';
  import { FieldInputAlign } from '@/enums/formEnum';
  import { onLoad } from '@dcloudio/uni-app';
  import { getDynamicDatas, getDynamicDataMultiple } from '@/services/api/form';
  import {
    DynamicDataModel,
    DynamicMultipleModel,
    DynamicParamModel,
    DynamicRuleModel,
  } from '@/services/model/formModel';
  import { ResultEnum } from '@/enums/httpEnum';
  import { Toast } from '@/utils/uniapi/prompt';

  const emits = defineEmits(['update:value', 'update:formData', 'labelShow']);

  const props = defineProps({
    value: {
      type: Object,
      default: () => null,
    },
    formData: {
      type: Object,
      default: () => {
        return {};
      },
    },
    required: {
      type: Boolean,
      default: false,
    },
    readonly: {
      type: Boolean,
      default: false,
    },
    //隐藏组件的公共属性
    formula: {
      type: Object,
      default: () => {
        return {
          showFormula: '', //回显用，因为包含表单字段的时候会出现表单名称
          calcFormula: '', //解析用，表单名称对应为formData.fieldxxxx
        };
      },
    },
    formItem: {
      type: Object,
      default: () => {},
    },
    // 必填规则
    rule: {
      type: Object,
      default: () => null,
    },
    placeholder: {
      type: String,
      default: '请输入内容',
    },
    enableScan: {
      type: Boolean,
      default: false,
    },
    // 数据流转规则
    rules: {
      type: Array<DynamicRuleModel>,
      default: () => {
        return [];
      },
    },
    // 关联流程
    dynamicData: {
      type: Array<string>,
      default: () => {
        return [];
      },
    },
    dynamicName: {
      type: Array<string>,
      default: () => {
        return [];
      },
    },
    // 过滤条件
    filters: {
      type: Object,
      default: () => {
        return {
          showFormula: '',
          calcFormula: '',
        };
      },
    },
    hidden: {
      type: Boolean,
      default: false,
    },
  });

  /** 计算属性：_value */
  const _value = computed({
    get() {
      return props.value;
    },
    set(val) {
      emits('update:value', val);
    },
  });

  /** 计算属性：_formData */
  const _formData = computed({
    get() {
      return props.formData;
    },
    set(val) {
      emits('update:formData', val);
    },
  });

  /** 校验规则 */
  const formRules = computed(() => {
    if (isEmpty(props.rule)) {
      return [];
    } else {
      return props.rule;
    }
  });

  const doFormula = () => {
    let hidden = evalFormual(props.formula.calcFormula, props.formData);
    //如果隐藏，同时也隐藏label,通知父组件去隐藏，因为label不在当前界面
    //调用父组件FormDesignRender 的方法：
    emits('labelShow', props.formItem, hidden);
  };

  watch(
    () => props.formData,
    () => {
      doFormula();
    },
    { immediate: true, deep: true },
  );

  const selectedLabel = ref('');
  const showPicker = ref(false);
  const options = ref<DynamicDataModel[]>([]);
  const customFieldName = {
    text: 'label',
    value: 'value',
  };

  /**
   * 确认选择
   * @param _value 选中的值
   */
  const onConfirm = (event: any) => {
    console.log(event);
    // 获取下拉选的value
    _value.value = event.selectedOptions[0];
    // 获取下拉选的text
    selectedLabel.value = event.selectedOptions[0].label;
    showPicker.value = false;
    // 处理数据流转规则
    handleData(event.selectedOptions[0].value);
  };

  /**
   * 处理数据流转
   */
  const handleData = (proInstId: string) => {
    if (isEmpty(props.rules)) {
      return;
    }

    let associatedFieldIds: any = [];
    const _rules: Array<DynamicRuleModel> = props.rules;
    _rules.forEach((item: DynamicRuleModel) => {
      if (item.associatedId.indexOf('_') != -1) {
        associatedFieldIds.push(item.associatedId.split('_')[0]);
      } else {
        associatedFieldIds.push(item.associatedId);
      }
    });

    const params = {
      proInstId: proInstId,
      fieldIds: associatedFieldIds,
    };

    getDynamicDataMultiple(params).then(({ data }) => {
      if (data.code == ResultEnum.SUCCESS) {
        data.data.forEach((item: DynamicMultipleModel, index) => {
          // 1.处理没有明细表的
          const rule = _rules.filter(
            (r) => r.associatedId == item.fieldId && r.associatedId.indexOf('_') == -1,
          );
          if (isNotEmpty(rule)) {
            rule.forEach((r) => {
              const label = item.label;
              if (isNotEmpty(label) && label.indexOf('label') != -1) {
                _formData.value[r.currentId] = getLabel(label);
              } else if (label.indexOf('[') != -1 || label.indexOf('{') != -1) {
                _formData.value[r.currentId] = JSON.parse(label);
              } else {
                _formData.value[r.currentId] = label;
              }
            });
          }
          // 2.处理明细表
          handleTableList(_rules, data.data);
        });
      }
    });
  };

  /**
   * 处理明细表数据
   * @param rules 数据流转规则
   * @param data 数据
   */
  const handleTableList = (rules: DynamicRuleModel[], data: DynamicMultipleModel[]) => {
    let associatedIds: string[] = [];
    let associatedFieldIds: string[] = [];
    let currentIds: string[] = [];
    let currentFields: string[] = [];
    rules
      .filter((r) => r.associatedId.indexOf('_') != -1)
      .forEach((r) => {
        const arr1 = r.associatedId.split('_');
        const arr2 = r.currentId.split('_');

        if (associatedIds.indexOf(arr1[0]) == -1 && currentIds.indexOf(arr2[0]) == -1) {
          associatedIds.push(arr1[0]);
          currentIds.push(arr2[0]);
        }
        if (associatedFieldIds.indexOf(arr1[1]) == -1 && currentFields.indexOf(arr2[1]) == -1) {
          associatedFieldIds.push(arr1[1]);
          currentFields.push(arr2[1]);
        }
      });
    // 处理数据
    data.forEach((item: DynamicMultipleModel, i: number) => {
      let tableList: any = [];

      const aIndex = associatedIds.indexOf(item.fieldId);
      if (aIndex != -1) {
        const aVal = JSON.parse(item.label);
        aVal.forEach((v: any) => {
          let tabObj: any = {};
          Object.keys(v).forEach((k) => {
            const kIndex = associatedFieldIds.indexOf(k);
            if (kIndex != -1) {
              const cVal = v[k];
              const cKey = currentFields[kIndex];
              tabObj[cKey] = cVal;
            }
          });
          tableList.push(tabObj);
        });
        _formData.value[currentIds[aIndex]] = tableList;
      }
    });
  };

  const getLabel = (label: string) => {
    let source = label.replace('{', '');
    source = source.replace('}', '');
    const arr1 = source.split(',');
    const arr2 = arr1.filter((item) => item.indexOf('label') != -1);
    if (isNotEmpty(arr2)) {
      const arr3 = arr2[0].split('=');
      if (isNotEmpty(arr3) && arr3.length > 1) {
        return arr3[1].trim();
      }
    }
    return '';
  };

  /**
   * 取消
   */
  const onCancel = () => {
    showPicker.value = false;
  };

  /**
   * 初始化
   */
  const init = () => {
    options.value = [];

    const params: DynamicParamModel = {
      groupId: props.dynamicData[0],
      formId: props.dynamicData[1],
      fieldId: props.dynamicData[2],
    };

    getDynamicDatas(params).then(({ data }) => {
      if (data.code == ResultEnum.SUCCESS) {
        if (isEmpty(props.filters.calcFormula)) {
          options.value = data.data;
        } else {
          options.value = data.data.filter((item) => {
            return evalFormual(props.filters.calcFormula, item.formData);
          });
        }
      } else {
        Toast(data.msg);
      }
    });
  };

  onLoad(() => {
    // 初始化
    init();
  });
</script>
<style scoped lang="scss"></style>
